//	Copyright (C) 2007 Christian Martick, http://juhu-mac.blogspot.com
//
//	Permission is hereby granted, free of charge, to any person obtaining a copy
//	of this software and associated documentation files (the "Software"), to deal
//	in the Software without restriction, including without limitation the rights
//	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//	copies of the Software, and to permit persons to whom the Software is
//	furnished to do so, subject to the following conditions:
//
//	The above copyright notice and this permission notice shall be included in
//	all copies or substantial portions of the Software.
//
//	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//	THE SOFTWARE.

#import "smcMainView.h"

extern NSString *kUIButtonBarButtonAction;
extern NSString *kUIButtonBarButtonInfo;
extern NSString *kUIButtonBarButtonInfoOffset;
extern NSString *kUIButtonBarButtonSelectedInfo;
extern NSString *kUIButtonBarButtonStyle;
extern NSString *kUIButtonBarButtonTag;
extern NSString *kUIButtonBarButtonTarget;
extern NSString *kUIButtonBarButtonTitle;
extern NSString *kUIButtonBarButtonTitleVerticalHeight;
extern NSString *kUIButtonBarButtonTitleWidth;
extern NSString *kUIButtonBarButtonType;

@implementation smcMainView

#pragma mark Helpers

- (NSString *) _lastSafariURLAsString
{
	// using the history plist to get latest page
	NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile: @"/var/root/Library/Safari/History.plist"];
	if (dict != nil)
	{
		// get latest url
		if ([[dict objectForKey: @"WebHistoryDates"] count] > 0)
			return [NSString stringWithString: [[[dict objectForKey: @"WebHistoryDates"] objectAtIndex: 0] objectForKey: @""]];
	}
	else 
		return @"";
}

- (NSString *) _trackPlayingAsString
{
	// using mobile music player framework
	// see 'Notes on using MobileMusikPlayer' for details
	
	// check if player running and if there is a track
	if (PCIsPlayerRunning() && (PCPlayerGetCurrentPlayingSong() != -1))
	{
		// create connection
		int iapConnection = PCCreateIAPConnection();
		
		// okay, first the id
		unsigned long long idSong = PCPlayerGetIdentifierAtIndex(NULL, PCPlayerGetCurrentPlayingSong());

		// now the title and the artist
		NSString *title = [NSString stringWithCString: 
			PCCopyStringValueForPropertyForIdentifier (iapConnection, kPropertySongTitle, idSong)];
		NSString *artist = [NSString stringWithCString: 
			PCCopyStringValueForPropertyForIdentifier (iapConnection, kPropertyArtist, idSong)];

		// close connection and return combined string
		PCCloseConnection(iapConnection);
		return [NSString stringWithFormat: @"%@ - %@", artist, title];
		
	} else
		return @"";

	/* 
		deprecated 
	*/

	// using itunes play count plist to get latest persistentID and MusicLibrary for track info
//	NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile: @"/var/root/Media/iTunes_Control/iTunes/PlayCounts.plist"];
//	if (dict != nil)
//	{
//		// get latest tracks uid
//		if ([[dict objectForKey: @"tracks"] count] > 0)
//		{
//			// find the latest track
//			int smallest = 0;
//			NSNumber *date = (NSNumber *)[[[dict objectForKey: @"tracks"] objectAtIndex: 0] objectForKey: @"playMacOSDate"];
//			for (int i = 1; i < [[dict objectForKey: @"tracks"] count]; i++)
//				if (([date compare: (NSNumber *)[[[dict objectForKey: @"tracks"] objectAtIndex: i] objectForKey: @"playMacOSDate"]] == NSOrderedAscending)
//					&& ([(NSNumber *)[[[dict objectForKey: @"tracks"] objectAtIndex: i] objectForKey: @"playMacOSDate"] longValue] != 0))
//				{
//					date = (NSNumber *)[[[dict objectForKey: @"tracks"] objectAtIndex: i] objectForKey: @"playMacOSDate"];
//					smallest = i;
//				}
//				
//			long long puid = [(NSNumber *)[[[dict objectForKey: @"tracks"] objectAtIndex: smallest] objectForKey: @"persistentID"] longLongValue];
//			
//			// find it in lib (may take some time)
//			
//			/* note: 
//				using mlquery the intended way would be better,
//				but as far as I know, there no properties for are
//				proper query known...
//			*/
//			
//			[MusicLibrary sharedMusicLibrary];
//			MLQuery *q = [[[MLQuery alloc] init] autorelease];
//			int foundAt = -1;
//			for (int i = 0; (i < [q countOfEntities]) && (foundAt == -1); i++)
//				if ([(MLTrack *) [q entityAtIndex: i] persistentUID] == puid)
//					foundAt = i;
//			
//			if (foundAt == -1)
//				return @"";
//			else
//			{
//				// put together the track infos
//				return [NSString stringWithFormat: @"%@ - %@", 
//					[(MLTrack *) [q entityAtIndex: foundAt] artist], [(MLTrack *)[q entityAtIndex: foundAt] title]];
//			}
//		}
//	}
//	else 
//		return @"";
}

- (void) _showKeyboard
{	
	// animated
	CGRect rect = [keys frame];
	rect.origin.y -= rect.size.height + 44.0f;

	[self addSubview: keys];
	
	[UIView beginAnimations: nil];
	[UIView setAnimationDuration: 0.3f];
	[UIView setAnimationDelegate: self];
	[UIView setAnimationDidStopSelector: @selector(keyboardShowAnimationDidEnd:)];
	[keys setFrame: rect];
	[insertSpecialsBar setOrigin: CGPointMake (0.0f, rect.origin.y - 44.0f)];
	rect.origin.y = 0.0f;
	rect.size.height = [self frame].size.height - rect.size.height -44.0f;
	[scrollView setFrame: rect];
	[UIView endAnimations];
	_keyboardHidden = NO;	
}

- (void) _hideKeyboard
{
	// animated

	CGRect rect = [keys frame];
	rect.origin.y += rect.size.height + 44.0f;
	
	[UIView beginAnimations: nil];
	[UIView setAnimationDuration: 0.3f];
	[UIView setAnimationDidStopSelector: @selector(keyboardHideAnimationDidEnd:)];
	[keys setFrame: rect];
	[insertSpecialsBar setOrigin: CGPointMake (0.0f, rect.origin.y - 44.0f)];
	rect.origin.y = 0.0f;
	rect.size.height = [self frame].size.height;
	[scrollView setFrame: rect];
	[UIView endAnimations];
	_keyboardHidden = YES;
}

#pragma mark The usual

- (void) dealloc 
{	
	[_content release];
	[insertSpecialsBar release];
	[picker release];
	[bubble release];
	[topBar release];
	[bottomBar release];
	[keys release];
	[scrollView release];
	[super dealloc];
}

- initWithFrame: (CGRect) rect
{
	self = [super initWithFrame: rect];
	if (self != nil)
	{
		_isCommentView = NO;
		_content = nil;
		
		// set color
		[self setBackgroundColor: [UIView colorWithRed: 0.0f green: 0.0f blue: 0.0f alpha: 1.0f]];
		
		// add navigation bars
		topBar = [[UINavigationBar alloc] initWithFrame: 
			CGRectMake(0.0f, 0.0f, rect.size.width, 44.0f)];
		[topBar setBarStyle: 2];
		[topBar setDelegate: self];
		[topBar showLeftButton: [UIImage applicationImageNamed:@"home.png"] withStyle: 0
			rightButton: @"Back" withStyle: 0];
			
		bottomBar = [[UINavigationBar alloc] initWithFrame:
			CGRectMake(0.0f, rect.size.height-44.0f, 320.0f, 44.0f)];
		[bottomBar setBarStyle: 2];
		[bottomBar setDelegate: self];
		[bottomBar showLeftButton: nil withStyle: 0	rightButton: @"Send!" withStyle: 1];
		[bottomBar setButton: 0 enabled: NO];
		
		// a bubble with all the text stuff
		bubble = [[smcBubbleView alloc] initWithFrame: 
			CGRectMake(rect.origin.x+15, 49.0f , rect.size.width-30, rect.size.height - 2*44.0f - 20.0f)];
		[bubble setDelegate: self];
		
		// a scroll view
		scrollView = [[UIScroller alloc] initWithFrame: CGRectMake(0.0f, 0.0f, rect.size.width, rect.size.height)];
		[scrollView setTapDelegate: self];		
		[scrollView addSubview: bubble];
		[scrollView setContentSize: CGSizeMake (rect.size.width-30, rect.size.height)];	
		[scrollView setScrollToPointAnimationDuration: 0.2f];
		
		// the icon picker
		picker = [[smcIconPicker alloc] initWithFrame: 
			CGRectMake(rect.origin.x + 15.0f, [bubble frame].origin.y + [bubble frame].size.height + 20.0f , rect.size.width-30, 50.0f)];
		[picker setDelegate: self];
		[picker setAlpha: 0.0f];
		[scrollView addSubview: picker];

		// and a label
		UITextLabel *label = [[[UITextLabel alloc] initWithFrame: 
			CGRectMake(0.0f, 0.0f, rect.size.width, 44.0f)] autorelease];
		[label setText: @"juhu"];
		[label setBackgroundColor: [UIView colorWithRed: 0.0f green: 0.0f blue: 0.0f alpha: 0.0f]];
		[label setColor: [UIView colorWithRed: 1.0f green: 1.0f	blue: 1.0f alpha: 1.0f]];
		[label setCentersHorizontally: YES];
		
		// keyboard
		[UIKeyboard initImplementationNow]; // not sure if needed, but http://www.cocoadev.com/index.pl?UIKeyboard says so
		keys = [[UIKeyboard alloc] initWithDefaultSize];
		CGRect keyrect = [keys frame];
		keyrect.origin = CGPointMake(0, [UIHardware fullScreenApplicationContentRect].size.height + 44.0f); // +44 space for button bar
		[keys setFrame: keyrect];
		_keyboardHidden = YES;
		
		// add as subviews		
		[self addSubview: scrollView];
		[self addSubview: topBar];
		[self addSubview: bottomBar];
		[self addSubview: label];
		[self addSubview: keys];
		
		// button bar for special inserts: safari url etc.
		NSDictionary *safari = [NSDictionary dictionaryWithObjectsAndKeys: 
			@"Add URL", kUIButtonBarButtonInfo, 
            [NSNumber numberWithUnsignedInt: 1], kUIButtonBarButtonTag,
			[NSNumber numberWithUnsignedInt: 3], kUIButtonBarButtonStyle,
            [NSNumber numberWithUnsignedInt: 1], kUIButtonBarButtonType,
			self, kUIButtonBarButtonTarget,
			@"insertSafari:", kUIButtonBarButtonAction, nil];
		
		NSDictionary *track = [NSDictionary dictionaryWithObjectsAndKeys: 
			@"Add Track", kUIButtonBarButtonInfo, 
            [NSNumber numberWithUnsignedInt: 2], kUIButtonBarButtonTag,
			[NSNumber numberWithUnsignedInt: 3], kUIButtonBarButtonStyle,
            [NSNumber numberWithUnsignedInt: 1], kUIButtonBarButtonType,
			self, kUIButtonBarButtonTarget,
			@"insertTrack:", kUIButtonBarButtonAction, nil];
		
		NSDictionary *done = [NSDictionary dictionaryWithObjectsAndKeys: 
			@"Done", kUIButtonBarButtonInfo, 
            [NSNumber numberWithUnsignedInt: 3], kUIButtonBarButtonTag,
			[NSNumber numberWithUnsignedInt: 2], kUIButtonBarButtonStyle,
            [NSNumber numberWithUnsignedInt: 1], kUIButtonBarButtonType,
			self, kUIButtonBarButtonTarget,
			@"done:", kUIButtonBarButtonAction, nil];
		
		NSArray *items = [NSArray arrayWithObjects: safari, track, done, nil];
		insertSpecialsBar = [[UIButtonBar alloc] initInView: self 
			withFrame: CGRectMake(0.0f, [UIHardware fullScreenApplicationContentRect].size.height, 
				[self frame].size.width, 44.0f) withItemList: items];
		[insertSpecialsBar setBarStyle: 1];

		int buttons[3] = {1, 2, 3};
		[insertSpecialsBar registerButtonGroup: 1 withButtons: buttons withCount: 3];
		[insertSpecialsBar showButtonGroup: 1 withDuration:0.0f];
	}
	
	return self;
}

#pragma mark Set and get and action

- (void) done: (id) sender
{
	// hide keyboard
	[self shouldHideKeyboardForView: self];
}

- (void) insertTrack: (id) sender
{
	NSString *new = [[bubble text] stringByAppendingString: [self _trackPlayingAsString]];
	if (([new length] > 140) && (![self isCommentView]))
		new = [new substringToIndex: 140];
	[bubble setText: new];
}

- (void) insertSafari: (id) sender
{
	NSString *new = [[bubble text] stringByAppendingString: [self _lastSafariURLAsString]];
	if (([new length] > 140) && (![self isCommentView]))
		new = [new substringToIndex: 140];
	[bubble setText: new];
}

- (void) setContentForComment: (NSDictionary *) newContent
{
	if (newContent != _content)
	{
		[_content release];
		_content = [newContent retain];
		[bubble setCommentTo: [_content objectForKey: kSmcEntryKeyFirstName]];
		[bubble setCommentToURL: [_content objectForKey: kSmcEntryKeyID]];
	}
}

- (void) resetView
{
	// no text, no icon, but location should remain
	[self setText: @""];
	
	if (!_isCommentView)
	{
		[picker resetIcons];
		[bubble setIcon: [picker selectedIcon]];
	}
}

- (void) setIsCommentView: (BOOL) yn
{
	if(_isCommentView != yn)
	{
		_isCommentView = yn;
		// give the bubble everything
		[bubble setIsComment: _isCommentView];
		if (_isCommentView)
			[self iconSelectedInPicker: picker]; // to hide if needed
	}	
}

- (BOOL) isCommentView
{
	return _isCommentView;
}

- (void) setText: (NSString *) text
{
	[bubble setText: text];
}

- (NSString *) text
{
	return [bubble text];
}

- (void) setLocation: (NSString *) text
{
	[bubble setLocation: text];
}

- (NSString *) location
{
	return [bubble location];
}

#pragma mark Navigation bar delegate

- (void)navigationBar: (UINavigationBar*) bar buttonClicked: (int) button 
{
	if (bar == topBar)
		switch (button)
		{
			case 0:
				if ([[self delegate] respondsToSelector: @selector(animateFromTo:)])
				{
					if (_isCommentView) // back to read view
						[[self delegate] performSelector: @selector(animateFromTo:) withObject: 
							[NSArray arrayWithObjects: self, [NSNumber numberWithInt: 3], nil]];
					else // back to overview
					{
						// save location and text first
						[[NSUserDefaults standardUserDefaults] setObject: [self text] forKey: @"text"];
						[[NSUserDefaults standardUserDefaults] setObject: [self location] forKey: @"location"];
						[[self delegate] performSelector: @selector(animateFromTo:) withObject: 
							[NSArray arrayWithObjects: self, [NSNumber numberWithInt: 0], nil]];
					}
				}
				break;
			case 1:
				if ([[NSUserDefaults standardUserDefaults] stringForKey: @"username"] != nil)
					[(UIApplication *) [self delegate] openURL: [NSURL URLWithString: 
						[NSString stringWithFormat: @"http://%@.jaiku.com", 
							[[NSUserDefaults standardUserDefaults] stringForKey: @"username"]]]];
				else
					[(UIApplication *) [self delegate] openURL: [NSURL URLWithString: @"http://jaiku.com"]];
				break;
		}
	else
	{
		// send button, fetch all the infos a tell delegate
		NSError *error = nil;
		NSMutableDictionary *info = [NSMutableDictionary dictionaryWithCapacity: 4];
		[info setObject: [NSNumber numberWithBool: _isCommentView] forKey: @"comment"];
		[info setObject: [[self text] copy] forKey: @"text"];
		
		if (_isCommentView)
			[info setObject: [bubble commentToURL] forKey: @"URL"];
		else
		{
			[info setObject: [[self location] copy] forKey: @"location"];
			[info setObject: [NSNumber numberWithInt: [picker selectedIconID]] forKey: @"icon"]; 
		}
		
		// send whatever is in info
		if ([[self delegate] respondsToSelector: @selector(sendSomething:)])
			error = [[self delegate] performSelector: @selector(sendSomething:) withObject: info];
	
		// okay, if comment: go back to read view if post okay, or show error and stay here on failure
		if ((_isCommentView) && (error != nil))
		{
			// show alert
			UIAlertSheet *alertSheet = [[[UIAlertSheet alloc] initWithTitle: @"Sorry"
				buttons: nil
				defaultButtonIndex: 0 
				delegate: nil
				context: nil] autorelease];
			[alertSheet setBodyText: @"Could not send comment, maybe try again."];
			[alertSheet popupAlertAnimated: YES];
		} else if ((_isCommentView) && ([[self delegate] respondsToSelector: @selector(animateFromTo:)]))
			[[self delegate] performSelector: @selector(animateFromTo:) withObject: 
				[NSArray arrayWithObjects: self, [NSNumber numberWithInt: 3], nil]]; // go back
	}
}

#pragma mark Bubble view delegate

- (void) textForPostDidChange: (id) sender
{
	// enable, disable send button
	if ([[bubble text] length] != 0)
		[bottomBar setButton: 0 enabled: YES];
	else
		[bottomBar setButton: 0 enabled: NO];
}

- (void) shouldShowKeyboardForView: (id) view
{
	if (_keyboardHidden)
		[self _showKeyboard];
	[bubble allowEditing];
	
}

- (void) shouldHideKeyboardForView: (id) view
{
	if (!_keyboardHidden)
		[self _hideKeyboard];
	[bubble forbidEditing];
}

- (void) iconAddButtonTappedInBubbleView: (id) view
{
	if ([picker alpha] == 1.0f)
	{
		// hide picker
		[self iconSelectedInPicker: picker];
		
	} else
	{
		// show icon picker
		[UIView beginAnimations: nil];
		[UIView setAnimationDuration: 0.2f];
		[picker setAlpha: 1.0f];
		[UIView endAnimations];
		
		// adjust scroller content height
		[scrollView setAdjustForContentSizeChange: YES]; // no idea if that works...
		CGSize size = [scrollView contentSize];
		size.height += 60.0f;
		[scrollView setContentSize: size];	
		
		// scroll to visible
		CGRect rect = [picker frame];
		rect.origin.y += 50.0f;
		[scrollView scrollRectToVisible: rect animated: YES];
	}
}

#pragma mark UIView animation delegate 

- (void) keyboardShowAnimationDidEnd: (id) sender
{
	// scroll view should make the first responder visible
	CGPoint convertPoint = [scrollView convertPoint: [[self firstResponder] frame].origin
		fromView: [[self firstResponder] superview]];
	float newY = convertPoint.y - [scrollView frame].size.height + [[self firstResponder] frame].size.height + 10.0f;

	if (newY > 0) // otherwise it is already visible!
		[scrollView scrollPointVisibleAtTopLeft: CGPointMake(0.0f, newY) animated: YES];

}

- (void) keyboardHideAnimationDidEnd: (id) sender
{
	// remove keyboard
	[keys removeFromSuperview];
}

#pragma mark Scroll view tap delegate

- (BOOL)view:(id)view handleTapWithCount: (int) count event: (struct __GSEvent *) event
{
	if (view == scrollView)
	{
		// if tapped in the scroll view void, maybe hide keyboard?
		//[scrollView scrollPointVisibleAtTopLeft: CGPointMake (0.0f, 0.0f) animated: YES];
		[self shouldHideKeyboardForView: view];
	}
}

#pragma mark smcIconPicker delegate

- (void) iconSelectedInPicker: (id) aPicker
{
	[bubble setIcon: [aPicker selectedIcon]];

	// hide if not hidden
	if ([aPicker alpha] != 0)
	{ 
		// adjust size
		[scrollView setAdjustForContentSizeChange: YES]; // no idea if that works...
		CGSize size = [scrollView contentSize];
		size.height -= 60.0f;
			
		// animate the picker away
		[UIView beginAnimations: nil];
		[UIView setAnimationDuration: 0.2f];
		[scrollView setContentSize: size];	
		[aPicker setAlpha: 0.0f];
		[UIView endAnimations];
	}
}

@end
